package com.ruoyi.analyse.service.impl;

import java.util.*;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.analyse.mapper.StudentLearningDimensionMapper;
import com.ruoyi.analyse.domain.StudentLearningDimension;
import com.ruoyi.analyse.service.IStudentLearningService;
import com.ruoyi.analyse.domain.QuestionAnalysis;
import com.ruoyi.analyse.mapper.QuestionAnalysisMapper;

/**
 * 学习进度分析实现类
 */
@Service
public class StudentLearningServiceImpl implements IStudentLearningService {

    @Autowired
    private StudentLearningDimensionMapper dimensionMapper;

    @Autowired
    private QuestionAnalysisMapper questionAnalysisMapper;

    /**
     * 维度颜色映射
     */
    private static final Map<String, String> DIMENSION_COLORS = new HashMap<>();
    static {
        DIMENSION_COLORS.put("基础知识", "#4361ee");
        DIMENSION_COLORS.put("实践能力", "#f72585");
        DIMENSION_COLORS.put("创新思维", "#f8961e");
        DIMENSION_COLORS.put("团队协作", "#43aa8b");
    }

    /**
     * 获取学生学习维度评估
     * @param userName 用户名
     * @return 学习维度列表
     */
    @Override
    public List<StudentLearningDimension> getStudentLearningDimensions(String userName) {
        // 检查是否已有维度评估，如果没有则计算
        List<StudentLearningDimension> dimensions = dimensionMapper.selectDimensionsByUserName(userName);
        if (dimensions == null || dimensions.isEmpty()) {
            calculateLearningDimensions(userName);
            dimensions = dimensionMapper.selectDimensionsByUserName(userName);
        }

        return dimensions;
    }

    /**
     * 计算学习维度评估
     * @param userName 用户名
     */
    @Override
    public void calculateLearningDimensions(String userName) {
        // 删除已有的维度评估
        dimensionMapper.deleteDimensionsByUserName(userName);

        // 获取用户的问题分析数据
        QuestionAnalysis questionAnalysis = new QuestionAnalysis();
        questionAnalysis.setUserName(userName);
        List<QuestionAnalysis> userQuestions = questionAnalysisMapper.selectQuestionAnalysisList(questionAnalysis);

        // 计算基础知识得分
        int baseKnowledgeScore = calculateBaseKnowledgeScore(userQuestions);

        // 计算实践能力得分
        int practicalAbilityScore = calculatePracticalAbilityScore(userQuestions);

        // 计算创新思维得分
        int innovativeThinkingScore = calculateInnovativeThinkingScore(userQuestions);

        // 计算团队协作得分
        int teamworkScore = calculateTeamworkScore(userQuestions);

        // 保存维度评估
        saveStudentDimension(userName, "基础知识", baseKnowledgeScore);
        saveStudentDimension(userName, "实践能力", practicalAbilityScore);
        saveStudentDimension(userName, "创新思维", innovativeThinkingScore);
        saveStudentDimension(userName, "团队协作", teamworkScore);
    }

    /**
     * 保存学生维度
     */
    private void saveStudentDimension(String userName, String dimensionName, int score) {
        StudentLearningDimension dimension = new StudentLearningDimension();
        dimension.setUserName(userName);
        dimension.setDimensionName(dimensionName);
        dimension.setScore(score);
        dimension.setColor(DIMENSION_COLORS.get(dimensionName));
        dimension.setCreateTime(new Date());
        dimension.setUpdateTime(new Date());

        dimensionMapper.insertStudentLearningDimension(dimension);
    }

    /**
     * 计算基础知识得分
     * 基于概念解释类问题、基础学科分布等
     */
    private int calculateBaseKnowledgeScore(List<QuestionAnalysis> questions) {
        // 计算总问题数
        int totalQuestions = getTotalQuestionCount(questions);
        if (totalQuestions == 0) return 60; // 无数据时的默认分数

        // 1. 概念解释问题占比 (0-40分)
        int conceptQuestions = 0;
        for (QuestionAnalysis q : questions) {
            if ("概念解释".equals(q.getQuestionType())) {
                conceptQuestions += q.getFrequency();
            }
        }
        double conceptRatio = totalQuestions > 0 ? (double) conceptQuestions / totalQuestions : 0;
        int conceptScore = (int) (conceptRatio * 40); // 概念问题比例越高，基础得分越高

        // 2. 学科覆盖度 (0-30分)
        Set<String> subjects = new HashSet<>();
        for (QuestionAnalysis q : questions) {
            if (q.getSubject() != null && !q.getSubject().isEmpty()) {
                subjects.add(q.getSubject());
            }
        }
        int subjectCoverage = Math.min(subjects.size() * 6, 30); // 每个学科6分，最高30分

        // 3. 学习持续性 (0-30分)
        int continuityScore = calculateLearningContinuity(questions);

        // 综合评分
        int finalScore = conceptScore + subjectCoverage + continuityScore;

        // 确保分数在0-100之间
        return Math.max(0, Math.min(100, finalScore));
    }

    /**
     * 计算实践能力得分
     * 基于代码实现、操作指导类问题等
     */
    private int calculatePracticalAbilityScore(List<QuestionAnalysis> questions) {
        // 计算总问题数
        int totalQuestions = getTotalQuestionCount(questions);
        if (totalQuestions == 0) return 60; // 无数据时的默认分数

        // 1. 实践相关问题占比 (0-50分)
        int practicalQuestions = 0;
        for (QuestionAnalysis q : questions) {
            if ("代码实现".equals(q.getQuestionType()) ||
                "操作指导".equals(q.getQuestionType()) ||
                "错误诊断".equals(q.getQuestionType())) {
                practicalQuestions += q.getFrequency();
            }
        }
        double practicalRatio = totalQuestions > 0 ? (double) practicalQuestions / totalQuestions : 0;
        int practicalScore = (int) (practicalRatio * 50);

        // 2. 问题解决复杂度 (0-50分)
        int complexityScore = 0;
        int complexQuestions = 0;
        int mediumQuestions = 0;

        for (QuestionAnalysis q : questions) {
            if (practicalQuestions > 0 && ("代码实现".equals(q.getQuestionType()) ||
                "操作指导".equals(q.getQuestionType()) ||
                "错误诊断".equals(q.getQuestionType()))) {
                if ("COMPLEX".equals(q.getComplexity())) {
                    complexQuestions += q.getFrequency();
                } else if ("MEDIUM".equals(q.getComplexity())) {
                    mediumQuestions += q.getFrequency();
                }
            }
        }

        // 根据复杂问题和中等问题的比例计算
        double complexRatio = practicalQuestions > 0 ?
            (double)(complexQuestions * 2 + mediumQuestions) / practicalQuestions : 0;
        complexityScore = (int) (complexRatio * 50);

        // 综合评分
        int finalScore = practicalScore + complexityScore;
        finalScore = finalScore / 2; // 取平均，确保不会超过100

        // 确保分数在0-100之间
        return Math.max(0, Math.min(100, finalScore));
    }

    /**
     * 计算创新思维得分
     * 基于问题复杂度、原理分析类问题等
     */
    private int calculateInnovativeThinkingScore(List<QuestionAnalysis> questions) {
        // 计算总问题数
        int totalQuestions = getTotalQuestionCount(questions);
        if (totalQuestions == 0) return 60; // 无数据时的默认分数

        // 1. 思考型问题占比 (0-40分)
        int thinkingQuestions = 0;
        for (QuestionAnalysis q : questions) {
            if ("原理分析".equals(q.getQuestionType()) ||
                "比较分析".equals(q.getQuestionType()) ||
                "优化建议".equals(q.getQuestionType())) {
                thinkingQuestions += q.getFrequency();
            }
        }
        double thinkingRatio = totalQuestions > 0 ? (double) thinkingQuestions / totalQuestions : 0;
        int thinkingScore = (int) (thinkingRatio * 40);

        // 2. 复杂问题比例 (0-40分)
        int complexQuestions = 0;
        for (QuestionAnalysis q : questions) {
            if ("COMPLEX".equals(q.getComplexity())) {
                complexQuestions += q.getFrequency();
            }
        }
        double complexRatio = totalQuestions > 0 ? (double) complexQuestions / totalQuestions : 0;
        int complexScore = (int) (complexRatio * 40);

        // 3. 问题多样性 (0-20分)
        Set<String> questionTypes = new HashSet<>();
        for (QuestionAnalysis q : questions) {
            if (q.getQuestionType() != null && !q.getQuestionType().isEmpty()) {
                questionTypes.add(q.getQuestionType());
            }
        }
        int diversityScore = Math.min(questionTypes.size() * 4, 20); // 每种问题类型4分，最高20分

        // 综合评分
        int finalScore = thinkingScore + complexScore + diversityScore;

        // 确保分数在0-100之间
        return Math.max(0, Math.min(100, finalScore));
    }

    /**
     * 计算团队协作得分
     * 可基于问题讨论频率、参与度等指标
     */
    private int calculateTeamworkScore(List<QuestionAnalysis> questions) {
        // 由于团队协作评估可能需要额外的数据源，这里提供一个更全面的计算方法
        // 如果可能，应集成其他系统数据（如论坛参与、项目协作等）

        // 计算总问题数
        int totalQuestions = getTotalQuestionCount(questions);
        if (totalQuestions == 0) return 65; // 无数据时的默认分数

        // 基础协作得分 - 基于现有数据的估算
        int baseScore = 65;

        // 如果有讨论类问题或团队相关问题，可以加分
        int discussionQuestions = 0;
        for (QuestionAnalysis q : questions) {
            String questionText = q.getKeyword().toLowerCase();
            if (questionText.contains("团队") ||
                questionText.contains("协作") ||
                questionText.contains("合作") ||
                questionText.contains("讨论") ||
                questionText.contains("交流")) {
                discussionQuestions += q.getFrequency();
            }
        }

        // 根据讨论问题比例调整分数
        double discussionRatio = totalQuestions > 0 ? (double) discussionQuestions / totalQuestions : 0;
        int adjustScore = (int) (discussionRatio * 25); // 最多加25分

        // 如果系统集成了其他协作数据，这里可以进一步调整分数

        // 综合评分
        int finalScore = baseScore + adjustScore;

        // 确保分数在0-100之间
        return Math.max(0, Math.min(100, finalScore));
    }

    /**
     * 计算学习持续性得分
     */
    private int calculateLearningContinuity(List<QuestionAnalysis> questions) {
        // 这需要问题的时间戳数据
        // 如果没有时间信息，可以基于问题数量和频率间接评估

        // 假设问题比较分散且数量适中，表示持续学习
        int frequencyScore = Math.min(questions.size() * 2, 30);

        return frequencyScore;
    }

    /**
     * 获取总问题数量
     */
    private int getTotalQuestionCount(List<QuestionAnalysis> questions) {
        int total = 0;
        for (QuestionAnalysis q : questions) {
            total += q.getFrequency();
        }
        return total;
    }



    /**
     * 根据学习维度评分计算学习状态
     * @param dimensions 学习维度列表
     * @return 学习状态描述
     */
    public String calculateLearningStatus(List<StudentLearningDimension> dimensions) {
        if (dimensions == null || dimensions.isEmpty()) {
            return "数据不足，无法评估";
        }

        // 找出最低分和最高分的维度
        StudentLearningDimension lowestDimension = null;
        StudentLearningDimension highestDimension = null;
        int totalScore = 0;

        for (StudentLearningDimension dim : dimensions) {
            totalScore += dim.getScore();

            if (lowestDimension == null || dim.getScore() < lowestDimension.getScore()) {
                lowestDimension = dim;
            }

            if (highestDimension == null || dim.getScore() > highestDimension.getScore()) {
                highestDimension = dim;
            }
        }

        // 计算平均分
        int avgScore = totalScore / dimensions.size();

        // 根据平均分确定整体状态
        String overallStatus;
        if (avgScore >= 85) {
            overallStatus = "优秀";
        } else if (avgScore >= 75) {
            overallStatus = "良好";
        } else if (avgScore >= 60) {
            overallStatus = "一般";
        } else {
            overallStatus = "需要提升";
        }

        // 结合最弱维度生成详细描述
        // 结合最弱维度生成详细描述
        StringBuilder status = new StringBuilder(overallStatus);

        if (lowestDimension != null && lowestDimension.getScore() < 70) {
            status.append(" - 建议重点提升");
            status.append(lowestDimension.getDimensionName());
        } else if (highestDimension != null && highestDimension.getScore() >= 80) {
            status.append(" - ");
            status.append(highestDimension.getDimensionName());
            status.append("表现突出");
        }


        return status.toString();
    }

    /**
     * 根据学习维度评分生成学习建议
     * @param dimensions 学习维度列表
     * @return 学习建议列表
     */
    public List<Map<String, String>> generateLearningRecommendations(List<StudentLearningDimension> dimensions) {
        List<Map<String, String>> recommendations = new ArrayList<>();

        // 建议库 - 每个维度对应多个不同分数段的建议
        Map<String, List<Map<String, Object>>> recommendationPool = new HashMap<>();

        // 基础知识建议 (10个不同等级)
        List<Map<String, Object>> baseKnowledgeRecs = new ArrayList<>();
        baseKnowledgeRecs.add(createRecommendation(
            "基础概念亟需巩固",
            "建议从最基本的概念开始重新学习，可以尝试使用入门级教材或视频课程，建立清晰的知识框架。",
            "el-icon-reading",
            0, 50
        ));
        baseKnowledgeRecs.add(createRecommendation(
            "查漏补缺核心知识",
            "您已经了解一些基础概念，但仍有较大知识空白，建议进行系统性学习，列出知识清单并逐一攻克。",
            "el-icon-notebook-1",
            50, 60
        ));
        baseKnowledgeRecs.add(createRecommendation(
            "加强基础理论学习",
            "建议通过结构化学习方式，如课程或教程，系统性填补知识漏洞，特别是核心理论部分。",
            "el-icon-collection",
            60, 65
        ));
        baseKnowledgeRecs.add(createRecommendation(
            "巩固知识连贯性",
            "您已掌握部分基础知识，但连贯性不足，建议绘制知识地图，理清概念之间的联系。",
            "el-icon-document",
            65, 70
        ));
        baseKnowledgeRecs.add(createRecommendation(
            "强化薄弱知识点",
            "已有一定基础，建议针对性地强化薄弱环节，可通过专项练习和针对性阅读提升。",
            "el-icon-edit-outline",
            70, 75
        ));
        baseKnowledgeRecs.add(createRecommendation(
            "系统整合知识体系",
            "您已具备较好的基础知识，现在需要将分散的知识点系统整合，形成完整的知识网络。",
            "el-icon-set-up",
            75, 79
        ));
        baseKnowledgeRecs.add(createRecommendation(
            "深化理论理解",
            "建议深入学习理论背后的原理，理解为什么而不仅是是什么，可以尝试阅读进阶教材或论文。",
            "el-icon-notebook-2",
            79, 85
        ));
        baseKnowledgeRecs.add(createRecommendation(
            "构建知识体系框架",
            "您的知识储备丰富，建议尝试构建自己的知识体系框架，可以通过写作或教授他人来巩固。",
            "el-icon-connection",
            85, 90
        ));
        baseKnowledgeRecs.add(createRecommendation(
            "拓展跨领域知识",
            "您的基础知识已相当扎实，可以尝试拓展到相关领域，建立知识间的连接，形成更广阔的视野。",
            "el-icon-data-analysis",
            90, 95
        ));
        baseKnowledgeRecs.add(createRecommendation(
            "探索前沿理论研究",
            "您的基础知识非常全面，建议关注领域前沿研究和最新发展，可以尝试阅读学术论文或参与研讨。",
            "el-icon-discover",
            95, 101
        ));
        recommendationPool.put("基础知识", baseKnowledgeRecs);

        // 实践能力建议 (10个不同等级)
        List<Map<String, Object>> practicalRecs = new ArrayList<>();
        practicalRecs.add(createRecommendation(
            "构建基础实践环境",
            "建议从搭建基础开发环境开始，熟悉基本工具的使用，完成简单的入门级实践项目。",
            "el-icon-setting",
            0, 50
        ));
        practicalRecs.add(createRecommendation(
            "跟随教程实践学习",
            "建议跟随详细教程完成一些基础项目，边学边做，培养动手能力。",
            "el-icon-guide",
            50, 60
        ));
        practicalRecs.add(createRecommendation(
            "完成小型独立项目",
            "尝试独立完成一些小型项目，培养解决问题的能力和实践经验。",
            "el-icon-tickets",
            60, 65
        ));
        practicalRecs.add(createRecommendation(
            "拓展技术工具应用",
            "学习并应用更多技术工具，提高开发效率，扩展技术栈广度。",
            "el-icon-suitcase",
            65, 70
        ));
        practicalRecs.add(createRecommendation(
            "参与协作实践项目",
            "尝试加入小型团队项目，在协作环境中提升实践能力，学习项目流程。",
            "el-icon-coordinate",
            70, 75
        ));
        practicalRecs.add(createRecommendation(
            "解决实际业务问题",
            "尝试解决一些实际业务场景中的问题，提升将理论转化为实践的能力。",
            "el-icon-cpu",
            75, 80
        ));
        practicalRecs.add(createRecommendation(
            "参与开源项目贡献",
            "加入开源社区，阅读优质代码并尝试做出贡献，在实践中学习工程最佳实践。",
            "el-icon-s-cooperation",
            80, 85
        ));
        practicalRecs.add(createRecommendation(
            "主导完整项目开发",
            "尝试独立主导一个完整项目的开发，从设计到实现，积累项目全流程经验。",
            "el-icon-s-management",
            85, 90
        ));
        practicalRecs.add(createRecommendation(
            "优化性能与架构",
            "专注于优化现有项目的性能和架构，学习高级技术和最佳实践，提升代码质量。",
            "el-icon-s-marketing",
            90, 95
        ));
        practicalRecs.add(createRecommendation(
            "探索技术前沿实践",
            "尝试应用前沿技术解决复杂问题，探索创新解决方案，挑战技术边界。",
            "el-icon-trophy",
            95, 101
        ));
        recommendationPool.put("实践能力", practicalRecs);

        // 创新思维建议 (10个不同等级)
        List<Map<String, Object>> innovativeRecs = new ArrayList<>();
        innovativeRecs.add(createRecommendation(
            "培养问题意识",
            "开始关注身边的问题和不便，培养发现问题的敏感度，这是创新的第一步。",
            "el-icon-question",
            0, 50
        ));
        innovativeRecs.add(createRecommendation(
            "学习基本思维工具",
            "学习基本的思维工具如思维导图、六顶思考帽等，辅助构建多角度思考能力。",
            "el-icon-bangzhu",
            50, 60
        ));
        innovativeRecs.add(createRecommendation(
            "培养发散思维习惯",
            "尝试对日常问题提出多种解决方案，不局限于第一个想到的答案，培养发散思维。",
            "el-icon-share",
            60, 65
        ));
        innovativeRecs.add(createRecommendation(
            "进行跨领域学习",
            "尝试学习不同领域的知识，将不同领域的思想和方法引入到自己的专业中。",
            "el-icon-files",
            65, 70
        ));
        innovativeRecs.add(createRecommendation(
            "参与创意讨论和头脑风暴",
            "积极参与团队创意讨论，在集体智慧的碰撞中培养创新思维能力。",
            "el-icon-chat-dot-square",
            70, 75
        ));
        innovativeRecs.add(createRecommendation(
            "分析优秀案例解决方案",
            "深入分析行业内优秀案例的解决方案，理解其创新点和思路。",
            "el-icon-view",
            75, 80
        ));
        innovativeRecs.add(createRecommendation(
            "学习设计思维方法",
            "系统学习设计思维方法，以用户为中心进行问题解决和创新设计。",
            "el-icon-s-grid",
            80, 85
        ));
        innovativeRecs.add(createRecommendation(
            "尝试原型设计和快速验证",
            "对创新想法进行原型设计和快速验证，通过迭代提升创新方案的可行性。",
            "el-icon-umbrella",
            85, 90
        ));
        innovativeRecs.add(createRecommendation(
            "主导创新项目实践",
            "尝试主导一个创新项目，从创意发想到落地实施，全面锻炼创新能力。",
            "el-icon-magic-stick",
            90, 95
        ));
        innovativeRecs.add(createRecommendation(
            "构建持续创新机制",
            "探索构建个人或团队的持续创新机制，将创新思维融入日常工作和学习中。",
            "el-icon-star-off",
            95, 101
        ));
        recommendationPool.put("创新思维", innovativeRecs);

        // 团队协作建议 (10个不同等级)
        List<Map<String, Object>> teamworkRecs = new ArrayList<>();
        teamworkRecs.add(createRecommendation(
            "理解基本团队角色",
            "了解团队中不同角色的职责和贡献，明确自己在团队中的定位和价值。",
            "el-icon-user",
            0, 50
        ));
        teamworkRecs.add(createRecommendation(
            "提升基础沟通能力",
            "练习清晰表达自己的想法，学会倾听他人观点，建立有效沟通的基础。",
            "el-icon-bell",
            50, 60
        ));
        teamworkRecs.add(createRecommendation(
            "积极参与团队讨论",
            "主动参与团队讨论和决策过程，表达自己的想法，增加团队贡献度。",
            "el-icon-chat-line-round",
            60, 65
        ));
        teamworkRecs.add(createRecommendation(
            "学习协作工具使用",
            "熟练掌握团队协作工具和平台，提高协作效率和信息共享质量。",
            "el-icon-s-tools",
            65, 70
        ));
        teamworkRecs.add(createRecommendation(
            "主动承担团队任务",
            "主动承担团队任务和责任，按时高质量完成，建立团队信任基础。",
            "el-icon-finished",
            70, 75
        ));
        teamworkRecs.add(createRecommendation(
            "处理团队冲突与分歧",
            "学习有效处理团队中的冲突和分歧，寻求建设性解决方案。",
            "el-icon-chat-dot-round",
            75, 80
        ));
        teamworkRecs.add(createRecommendation(
            "学习项目管理方法",
            "掌握基本的项目管理知识和方法，提升团队协作中的计划和执行能力。",
            "el-icon-s-check",
            80, 85
        ));
        teamworkRecs.add(createRecommendation(
            "担任团队协调角色",
            "尝试在团队中担任协调和组织角色，促进团队成员间的合作和信息流通。",
            "el-icon-s-custom",
            85, 90
        ));
        teamworkRecs.add(createRecommendation(
            "培养团队引导能力",
            "发展引导团队讨论和决策的能力，帮助团队聚焦目标，提高效率。",
            "el-icon-s-flag",
            90, 95
        ));
        teamworkRecs.add(createRecommendation(
            "建立高效团队文化",
            "帮助建立积极、透明、高效的团队文化，促进团队创新和成长。",
            "el-icon-s-opportunity",
            95, 101
        ));
        recommendationPool.put("团队协作", teamworkRecs);
        // 学习效率建议 - 通用建议，始终添加
        Map<String, String> efficiencyRec = new HashMap<>();
        efficiencyRec.put("icon", "el-icon-data-line");
        efficiencyRec.put("title", "关注学习效率");
        efficiencyRec.put("description", "建议制定合理的学习计划，定期复习，提高学习效率。");
        recommendations.add(efficiencyRec);

        // 为每个维度选择一个适合的建议
        for (StudentLearningDimension dimension : dimensions) {
            List<Map<String, Object>> dimensionRecs = recommendationPool.get(dimension.getDimensionName());
            if (dimensionRecs != null) {
                for (Map<String, Object> rec : dimensionRecs) {
                    int minScore = (int) rec.get("minScore");
                    int maxScore = (int) rec.get("maxScore");

                    if (dimension.getScore() >= minScore && dimension.getScore() < maxScore) {
                        Map<String, String> recommendation = new HashMap<>();
                        recommendation.put("icon", (String) rec.get("icon"));
                        recommendation.put("title", (String) rec.get("title"));
                        recommendation.put("description", (String) rec.get("description"));
                        recommendations.add(recommendation);
                        break;  // 每个维度只选一个建议
                    }
                }
            }
        }

        // 最多返回3个建议
        if (recommendations.size() > 4) {
            recommendations = recommendations.subList(0, 4);
        }

        return recommendations;
    }

    /**
     * 创建建议对象
     */
    private Map<String, Object> createRecommendation(String title, String description, String icon, int minScore, int maxScore) {
        Map<String, Object> rec = new HashMap<>();
        rec.put("title", title);
        rec.put("description", description);
        rec.put("icon", icon);
        rec.put("minScore", minScore);
        rec.put("maxScore", maxScore);
        return rec;
    }

}
